import React, { useCallback, useState } from "react";
import { Input } from "antd";
/**useCallback 用于优化性能，返回一个记忆化的回调函数，可以减少不必要的重新渲染，也就是说它是用于缓存组件内的函数，避免函数的重复创建。
 * 入参
callback：回调函数
deps：依赖项数组，当依赖项发生变化时，回调函数会被重新创建，跟useEffect一样。
返回值
返回一个记忆化的回调函数，可以减少函数的创建次数，提高性能。

注意:
useCallback的使用需要有所节制，不要盲目地对每个方法应用useCallback，这样做可能会导致不必要的性能损失。useCallback本身也需要一定的性能开销。
useCallback并不是为了阻止函数的重新创建，而是通过依赖项来决定是否返回新的函数或旧的函数，从而在依赖项不变的情况下确保函数的地址不变。
 * @returns 
 */

// 测试输入不触发子组件渲染
export function UseCallbackDemo() {
  const [use, setUse] = useState({ name: "张三", age: 18 });
  const changeInput = (e: React.ChangeEvent<HTMLInputElement>) => {
    setUse({ name: e.target.value, age: 18 });
  };
  const callBack1 = () => {
    console.log("点击了");
  };
  const callback = useCallback(() => {
    console.log("点击了==>useCallback");
  }, []);
  return (
    <div>
      <h1>useCallback</h1>
      <Input placeholder="请输入" onChange={(e) => changeInput(e)}></Input>
      {/* <ChildComponent use={use} callback={callBack1} /> */}
      <ChildComponent callback={callback} />
    </div>
  );
}

// 子组件
// 如果props包含函数且不通过useCallback处理，那么每次父组件重新渲染时，
// 子组件都会重新渲染，因为函数是引用类型，每次都会创建新的函数，导致子组件的props发生变化，从而触发子组件的重新渲染。
const ChildComponent = React.memo(
  ({
    // use,
    callback,
  }: {
    // use: { name: string; age: number };
    callback: () => void;
  }) => {
    console.log("子组件渲染===>useCallback==>");
    return (
      <div>
        {/* <p>{use.name}</p>
        <p>{use.age}</p> */}
        <button onClick={callback}>点击</button>
      </div>
    );
  }
);
